<template>
  <el-dialog :title="title" :visible.sync="visible" width="920px" append-to-body :close-on-click-modal="false" @closed="reset">
    <el-row :gutter="40">
      <el-col :span="12" :xs="24">
        <div class="head-container">
          <el-input
            v-model="search"
            placeholder="请输入关键字"
            clearable
            size="small"
            prefix-icon="el-icon-search"
            style="margin-bottom: 20px"/>
        </div>
        <div class="head-container selector-tree">
          <el-tree
            ref="tree"
            v-loading="treeLoading"
            :props="defaultProps"
            :data="treeData"
            node-key="id"
            show-checkbox
            check-strictly
            :expand-on-click-node="false"
            :default-expanded-keys="treeExpandData"
            :filter-node-method="filterNode"
            highlight-current
            @check="handleCheck"/>
        </div>
      </el-col>
      <el-col :span="12" :xs="24">
        <el-form :model="form" :rules="rules" ref="form" label-position="top">
          <el-form-item label="已选项" prop="selections">
            <div style="min-width: 200px;min-height: 8px">
              <el-tag v-for="(item, index) in form.selections" :key="item.id" closable @close="handleClose(index)" class="user-tag">{{ item.name }}</el-tag>
            </div>
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>

    <div slot="footer" class="dialog-footer">
      <el-button type="primary" @click="select">确 定</el-button>
      <el-button @click="close">取 消</el-button>
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: "Tree",
  props: {
    title: {
      type: String,
      default: "选择"
    },
    defaultProps: {
      type: Object,
      default: () => {
        return {
          children: "children",
          label: "name",
          disabled: (data) => {
            return data.disabled === "1"
          }
        };
      }
    },
    multipleMode: {
      type: Boolean,
      default: true
    },
    initFn: Object
  },
  data() {
    const validateSelections = (rule, value, callback) => {
      if (!value || value.length === 0) {
        callback(new Error('请至少选择一个值'));
        return;
      }

      // 非多选模式
      if (!this.multipleMode) {
        if (value.length > 1) {
          callback(new Error('只能选择一个值'));
          return;
        }
      }
      callback();
    };

    return {
      visible: false,
      search: undefined,
      treeLoading: false,
      treeData: [],
      treeExpandData:[],
      form: {
        // 选中数组
        selections: [],
      },
      // 表单校验
      rules: {
        selections: [
          { validator: validateSelections, trigger: 'change' }
        ]
      }
    }
  },
  watch: {
    // 根据名称筛选部门树
    search(val) {
      this.$refs.tree.filter(val);
    }
  },
  methods: {
    init(selections) {
      this.visible = true;
      this.form.selections = selections || [];
      this.initTreeData();
    },
    initTreeData() {
      if (this.initFn && this.initFn.fn) {
        const fn = this.initFn.fn;
        const params = this.initFn.params;

        this.treeLoading = true;
        fn(params).then(res => {
          this.treeLoading = false;

          this.treeData = res;
          this.initSelection();
        }).catch(() => {
          this.treeLoading = false;
        });
      } else {
        this.initSelection();
      }
    },
    initSelection() {
      this.$lodash.forEach(this.treeData, item => {
        this.treeExpandData.push(item.id);
      });

      this.$nextTick(() => {
        const ids = [];
        this.$lodash.forEach(this.form.selections, item => {
          ids.push(item.id);
        });
        this.$refs.tree.setCheckedKeys(ids);
      });
    },
    // 筛选节点
    filterNode(value, data) {
      if (!value) {
        return true;
      }
      return data[this.defaultProps.label].indexOf(value) !== -1;
    },
    handleCheck(data, checked) {
      const checkedKeys = checked.checkedKeys;
      const index = this.$lodash.findIndex(checkedKeys, function(o) { return o === data.id; });
      if (index > -1) {
        const selection = this.$lodash.filter(this.form.selections, function(o) { return o.id === data.id; });
        if (!selection || selection.length === 0) {
          const newSelection = {
            id: data.id,
            name: data.name
          }
          this.form.selections.push(newSelection);
        }
      } else {
        const index = this.$lodash.findIndex(this.form.selections, function(o) { return o.id === data.id; });
        this.spliceData(index, false);
      }
    },
    handleClose(index) {
      this.spliceData(index, true);
    },
    spliceData(index, changeCheck) {
      if (changeCheck) {
        const selection = this.form.selections[index];
        this.$refs.tree.setChecked(selection.id, false);
      }
      this.form.selections.splice(index, 1);
    },
    select() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          this.$emit("set-value", this.form.selections);
          this.close();
        }
      });
    },
    close() {
      this.visible = false;
    },
    // 表单重置
    reset() {
      this.search = undefined;
      this.treeData = [];
      this.form.selections = [];
      this.resetForm("form");
    }
  }
}
</script>

<style scoped lang="scss">
  .selector-tree {
    height: 60vh;
    overflow: auto;
    & ::v-deep .el-tree {
      display: inline-block;
    }

    & ::v-deep .el-tree__empty-text {
      display: contents;
    }
  }

  .user-tag {
    margin-right: 8px;
  }
</style>
